package com.example.sunny.view.weather

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.icu.util.Calendar
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.SystemClock
import android.util.Log
import android.view.*
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import com.example.sunny.R
import com.example.sunny.pojo.weather.Weather
import com.example.sunny.pojo.weather.getSky
import kotlinx.android.synthetic.main.activity_weather.*
import kotlinx.android.synthetic.main.forecast_weather.*
import kotlinx.android.synthetic.main.life_index.*
import kotlinx.android.synthetic.main.now_weather.*
import java.text.SimpleDateFormat
import java.util.*
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.sunny.pojo.weather.DailyResponse
import com.example.sunny.pojo.weather.RealTimeResponse
import com.example.sunny.view.map.MapViewActivity
import kotlin.collections.ArrayList
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.FileProvider
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkRequest
import com.example.sunny.SunnyApplication
import com.example.sunny.pojo.location.MyLocation
import com.example.sunny.service.dao.ApplicationDao.updateDB
import com.example.sunny.service.network.location.LocationService
import com.example.sunny.service.receiver.AlarmTimer
import com.example.sunny.service.work.WeatherNotificationWorker
import com.example.sunny.utils.FileUtils.storeBitmap
import com.example.sunny.utils.NetUtils
import com.example.sunny.utils.UIUtils
import com.example.sunny.utils.UIUtils.replaceFragment
import java.io.File
import java.util.concurrent.TimeUnit

class WeatherActivity : AppCompatActivity(), LocationService.MyLocationListener.LocationCallback{

    private val TAG = "WeatherActivity"

    val viewModel by lazy {
        ViewModelProvider(this).get(WeatherViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //状态栏与背景融合
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        val option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        val vis: Int = window.decorView.systemUiVisibility
        window.decorView.systemUiVisibility = option or vis
        window.statusBarColor = Color.TRANSPARENT
        setContentView(R.layout.activity_weather)

        if (NetUtils.isNetWorkConnected(SunnyApplication.context)){
            viewModel.isNetConnected.value = true
        }

//        AlarmTimer.setRepeatingAlarmTimer(SunnyApplication.context,SystemClock.elapsedRealtime(),(60*1000).toLong(),AlarmTimer.TIMER_ACTION_REPEATING,
//            AlarmManager.ELAPSED_REALTIME)

        val notificationWorkRequest = PeriodicWorkRequestBuilder<WeatherNotificationWorker>(15,TimeUnit.SECONDS).build()

        WorkManager.getInstance(SunnyApplication.context).enqueueUniquePeriodicWork("weatherNotification",ExistingPeriodicWorkPolicy.KEEP,notificationWorkRequest)

        WorkManager.getInstance(SunnyApplication.context)
            .getWorkInfoByIdLiveData(notificationWorkRequest.id)
            .observe(this){ workInfo->
                val progress = workInfo.progress
                val value = progress.getInt("progress",0)
                Log.d("$TAG-progress",value.toString())

            }

        //观察weatherLiveData
        viewModel.weatherLiveData.observe(this){result->
            val weather = result.getOrNull()
            Log.d("WeatherActivity",weather.toString())
            if (weather!=null){
                showWeatherInfo(weather)
            }else{
//                "无法获取天气信息".showToast()
                result.exceptionOrNull()?.printStackTrace()
            }
            swipeRefresh.isRefreshing = false
        }

        viewModel.isNetConnected.observe(this){  isConnected->
            if (isConnected){
                viewModel.locationClient = LocationService.initLocation(SunnyApplication.context, this)
                Log.d(TAG,"已开启定位")
            }else{
                refreshWeather()
            }

        }

        viewModel.isCentigrade.observe(this){
            refreshWeather()
        }

        //设置控件监听器
        setWidgetListeners()
        //检查许可
        checkPermission()
        //设置手动刷新
        swipeRefresh.setColorSchemeResources(R.color.blue)
        swipeRefresh.setOnRefreshListener {
            viewModel.locationClient?.start()
            viewModel.refreshWeather()
        }


    }

     fun refreshWeather(){
        viewModel.refreshWeather()
        swipeRefresh.isRefreshing = true
    }

    private fun setWidgetListeners(){
        navBtn.setOnClickListener {
            drawerLayout.openDrawer(GravityCompat.START)
        }

        menuBtn.setOnClickListener {
            showPopMenu(it)
        }

        btnMap.setOnClickListener {

            val intent = Intent(this, MapViewActivity::class.java).apply {
                putExtra("my_location",viewModel.myLocation)
            }
            startActivity(intent)
            viewModel.locationClient?.stop()
        }

        floatingBtn.setOnClickListener{
            Log.d(TAG,"floatingBtn点击")
            viewModel.locationClient?.start()
            viewModel.locationClient?.requestLocation()
        }


        btnShowMore.setOnClickListener {
            if (viewModel.isShowing){
                moreDaysForecastLayout.visibility = View.GONE
                btnShowMore.text = "查看更多"
                viewModel.isShowing = !viewModel.isShowing
            }else{
                moreDaysForecastLayout.visibility = View.VISIBLE
                btnShowMore.text = "收起"
                viewModel.isShowing = !viewModel.isShowing
            }
        }

        drawerLayout.addDrawerListener(object :DrawerLayout.DrawerListener{
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
            }

            override fun onDrawerOpened(drawerView: View) {
            }

            override fun onDrawerClosed(drawerView: View) {
                val manager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                manager.hideSoftInputFromWindow(drawerView.windowToken,InputMethodManager.HIDE_NOT_ALWAYS)
            }

            override fun onDrawerStateChanged(newState: Int) {

            }

        })

    }

    private fun showWeatherInfo(weather:Weather){
        if (viewModel.myLocation==null){
            viewModel.refreshLocation()
        }
        now_placeName.text= "${viewModel.myLocation?.city} ${viewModel.myLocation?.street}"
        val realtime = weather.realtime

        val daily = weather.daily

        //填充now_weather
        inflateNowWeather(realtime)

        //填充forecast
        inflateForecastWeather(daily)

        //填充life_index
        inflateLifeIndex(daily)

        //设置背景图片及透明度
        weatherLayout.visibility = View.VISIBLE
        weatherLayout.setBackgroundResource(getSky(realtime.skycon).bg)
        weatherLayout.background.alpha = 250
        //更新数据库
        viewModel.myLocation?.let { updateDB(it,daily) }

    }

    //填充now_weather
    private fun inflateNowWeather(realtime:RealTimeResponse.Realtime){
        val currentTempText = if (viewModel.isCentigrade.value!!){
            "${realtime.temperature.toInt()} ℃"
        }else{
            "${(realtime.temperature*33.8f).toInt()} ℉"
        }




        currentTemp.text = currentTempText
        currentSky.text = getSky(realtime.skycon).info

        val currentPM25TexT = "空气指数 ${realtime.airQuality.aqi.chn.toInt()}"
        currentAQI.text =currentPM25TexT
    }

    //填充forecast
    private fun inflateForecastWeather(daily:DailyResponse.Daily){
        threeDaysForecastLayout.removeAllViews()
        moreDaysForecastLayout.removeAllViews()
        val days = daily.skycon.size

        for (i in 0 until days){
            val skycon = daily.skycon[i]
            val temperature = daily.temperature[i]
            var view:View
            if (i<3){
                 view = LayoutInflater.from(this).inflate(R.layout.forecast_weather_item,threeDaysForecastLayout,false)
                 threeDaysForecastLayout.addView(view)
            }else{
                 view = LayoutInflater.from(this).inflate(R.layout.forecast_weather_item,moreDaysForecastLayout,false)
                 moreDaysForecastLayout.addView(view)
            }

            val dateInfo = view.findViewById<TextView>(R.id.dateInfo)
            val skyIcon = view.findViewById<ImageView>(R.id.skyIcon)
            val skyInfo = view.findViewById<TextView>(R.id.skyInfo)
            val temperatureInfo = view.findViewById<TextView>(R.id.temperatureInfo)

            val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            dateInfo.text = simpleDateFormat.format(skycon.date)
            val sky = getSky(skycon.value)
            skyIcon.setImageResource(sky.icon)
            skyInfo.text  =sky.info
            val tempText = if (viewModel.isCentigrade.value!!){
                "${temperature.min.toInt()} ~ ${temperature.max.toInt()} ℃"
            }else{
                "${(temperature.min*33.8f).toInt()} ~ ${(temperature.max*33.8f).toInt()} ℉"
            }
            temperatureInfo.text = tempText

            view.setOnClickListener {
                val bundle = Bundle().apply {
                    putParcelable("daily",daily)
                    putInt("position",i)
                    putBoolean("is_centigrade",viewModel.isCentigrade.value!!)
                }
                val fragment = DailyWeatherFragment()
                fragment.arguments = bundle
                replaceFragment(this,R.id.dailyWeatherFragmentLayout,fragment)
                dailyWeatherFragmentLayout.visibility = View.VISIBLE
                normalLayout.visibility = View.GONE
            }
        }
        forecastLayout.background?.alpha = 255
        btnShowMore.width = forecastLayout.width * (2/3)
    }

    //填充life_index
    private fun inflateLifeIndex(daily:DailyResponse.Daily){
        UIUtils.InflateUI.inflateLifeIndex(lifeIndexLayout,daily,0)
        lifeIndexLayout.background?.alpha = 255
    }

    private fun checkPermission(){
        val permissionList = ArrayList<String>()
        for (permission in viewModel.permissionList) {
            if (ContextCompat.checkSelfPermission(this,permission)!=PackageManager.PERMISSION_GRANTED){
                permissionList.add(permission)
            }
        }
        val permissions = permissionList.toTypedArray()
        if (permissions.isNotEmpty()){
            ActivityCompat.requestPermissions(this,permissions,1)

        }
    }

    override fun onBackPressed() {
        dailyWeatherFragmentLayout.visibility = View.GONE
        normalLayout.visibility = View.VISIBLE
        super.onBackPressed()

    }

    override fun getLocation(myLocation: MyLocation) {
        Log.d("Location",myLocation.toString())
        viewModel.myLocation = myLocation
        refreshWeather()
    }

    override fun onDestroy() {
        viewModel.locationClient?.requestLocation()
        super.onDestroy()
    }


    private fun showPopMenu( menu:View){
        val popupMenu = PopupMenu(this, menu)
        popupMenu.menuInflater.inflate(R.menu.overflow_menu,popupMenu.menu)
        popupMenu.setOnMenuItemClickListener { item ->
            when (item?.itemId) {
                R.id.share -> share()
                R.id.settings -> settings()
            }
            true
        }
        popupMenu.show()
    }

    private fun share(){
        val rootView = window.decorView.findViewById<View>(android.R.id.content)
        val bitmap = getScreenshot(rootView)
        val file = storeBitmap(bitmap, "/${viewModel.myLocation?.city}天气.png",this)
        shareImage(file)

    }

    private fun settings(){
        val fragment = SettingsFragment()
        fragment.arguments?.putBoolean("is_centigrade",viewModel.isCentigrade.value?:true)
        replaceFragment(this,R.id.dailyWeatherFragmentLayout,fragment)
        dailyWeatherFragmentLayout.visibility = View.VISIBLE
        normalLayout.visibility = View.GONE
    }

    private fun getScreenshot(view: View):Bitmap{
        val screenView = view.rootView
        screenView.isDrawingCacheEnabled = true
        val bitmap = Bitmap.createBitmap(screenView.drawingCache)
        screenView.isDrawingCacheEnabled = false
        return bitmap
    }


    private fun shareImage( file:File){
        val imgUri = FileProvider.getUriForFile(this,"com.example.sunny.fileprovider",file)
        val intent = Intent().apply {
            action = Intent.ACTION_SEND
            type = "image/*"
            putExtra(Intent.EXTRA_SUBJECT,"")
            putExtra(Intent.EXTRA_TEXT,"")
            putExtra(Intent.EXTRA_STREAM,imgUri)
        }
        startActivity(Intent.createChooser(intent,"选择"))
    }

}

